import subprocess
import os.path
import re
import time


class Project():
    files = []
    changesets = []

    def __init__(self, directory):
        self.path = directory
        self.name = os.path.basename(directory)
        self.branch_name = ""

    def refresh(self):
        self.status()
        self.outgoing()
        self.branch()


    def status(self):
        file_lines = self.mercurial("status")
        self.files = FileFactory.parse(file_lines)


    def outgoing(self):
        changeset_lines = self.mercurial("outgoing")
        self.changesets = ChangesetFactory.parse(changeset_lines)

    def branch(self):
        self.branch_name = self.mercurial("branch").strip()


    def mercurial(self, args):
        command = ["hg", "-R", self.path]
        command.append(args)
        pipe = subprocess.Popen(command, stdout=subprocess.PIPE)
        out, err = pipe.communicate()
        return out

    def is_clean(self):
        return len(self.changesets) == 0 and len(self.files) == 0


    def get_row(self):
        row = [self.name, self.branch_name, len(self.files), len(self.changesets), self.path]
        print(row)
        return row


class ProjectCache:
    projects = {}

    def __init__(self, config):
        self.config = config

    def add_project(self, project):
        self.projects[project.path] = project
        self.persist()

    def remove_project(self, project):
        del self.projects[project.path]
        self.persist()

    def get_project(self, path):
        if path in self.projects.keys():
            return self.projects[path]
        else:
            return None

    def get_projects(self):
        return self.projects.values()

    def has_project(self, path):
        return path in self.projects

    def persist(self):
        self.config.persist_projects(self.projects.values())


class ChangesetFactory:
    @staticmethod
    def parse(text):
        date_pattern = r"date: *"
        summary_pattern = r"summary: *"
        date_format = "%a %b %d %H:%M:%S %Y"

        changesets = []
        lines = text.splitlines()
        date = None
        summary = None
        for line in lines:
            if re.match(date_pattern, line) != None:
                date = time.strptime(re.sub(date_pattern, "", line)[:-6], date_format)
            if re.match(summary_pattern, line) != None:
                summary = re.sub(summary_pattern, "", line)
            if date != None and summary != None:
                changesets.append(Changeset(date, summary))
                date = None
                summary = None
        return changesets


class Changeset:
    def __init__(self, date, summary):
        self.date = date
        self.summary = summary

    def get_row(self):
        return [time.strftime("%a %H:%M", self.date), self.summary]

    def to_string(self):
        return time.strftime("%a %H:%M", self.date) + " - " + self.summary


class FileFactory:
    @staticmethod
    def parse(text):
        files = []
        lines = text.splitlines()
        for line in lines:
            if len(line) > 2:
                files.append(File(line[0], line[2:]))
        return files

class File:
    def __init__(self, status, path):
        self.path = path
        self.status = status

    def get_row(self):
        return [self.status, self.path]

    def to_string(self):
        return "[" + self.status + "] " + self.path
